﻿using ApiLib.AppStart;
using ApiLib.Cloud.Models;
using ApiLib.Helpers;
using ApiLib.Utils;
using Furion;
using SqlSugar;

namespace ApiLib.Cloud.Common;

/// <summary>
/// 常量
/// </summary>
public static class MyCloudConstants
{
    /// <summary>
    /// 服务类型
    /// </summary>
    public static CloudModalType CloudType => Config.IsZuul ? CloudModalType.Zuul : CloudModalType.Service;

    /// <summary>
    /// Swagger分组
    /// </summary>
    public const string ApiDescriptionSettings = "ApiLib.Cloud";
    /// <summary>
    /// 服务信息
    /// </summary>
    public static ServiceConfig? Config = null;

    /// <summary>
    /// 是否是网关
    /// </summary>
    public static bool IsZuul => Config.IsZuul;

    /*/// <summary>
    /// 所有服务
    /// </summary>
    public static List<ServiceInfo> ServiceInfos => GlobalCache.Get<List<ServiceInfo>>(nameof(ServiceInfo));

    /// <summary>
    /// 所有路由
    /// </summary>
    public static List<SysCloudRoute> CloudRoutes => GlobalCache.Get<List<SysCloudRoute>>(nameof(SysCloudRoute));*/


    /// <summary>
    /// 请求地址
    /// </summary>
    public static class Url
    {
        /// <summary>
        /// 健康检查
        /// </summary>
        public static readonly string Health = Config.ZuulUrl + "/api/Cloud/Health";

        /// <summary>
        /// 注册
        /// </summary>
        public static readonly string Register = Config.ZuulUrl + "/api/Cloud/Register";
    }

    /// <summary>
    /// 数据库
    /// </summary>
    public static ISqlSugarClient Db => WebApp.Db;
}

/// <summary>
/// 服务中心
/// </summary>
public static class CloudUtil
{
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public static List<SysCloudRoute> GetRoute(bool init = false)
    {
        var routes = GlobalCache.Get<List<SysCloudRoute>>(nameof(SysCloudRoute));
        if (init || routes.IsNullOrEmpty())
        {
            routes = DbHelper.Db.Queryable<SysCloudRoute>().ToList();
            GlobalCache.Set(nameof(SysCloudRoute), routes);
        }
        routes ??= new List<SysCloudRoute>();
        return routes;
    }

    /// <summary>
    /// 获取
    /// </summary>
    /// <returns></returns>
    public static List<ServiceInfo> GetServiceInfo(bool init = false)
    {
        var serviceInfos = GlobalCache.Get<List<ServiceInfo>>(nameof(ServiceInfo));
        if (init || serviceInfos.IsNullOrEmpty())
        {
            if (!serviceInfos.IsNullOrEmpty())
            {
                UpdateServiceInfo(serviceInfos);
            }
            serviceInfos = DbHelper.Db.Queryable<ServiceInfo>().ToList();
            GlobalCache.Set(nameof(ServiceInfo), serviceInfos);
        }

        serviceInfos ??= new List<ServiceInfo>();
        return serviceInfos;
    }

    /// <summary>
    /// 更新
    /// </summary>
    public static void UpdateServiceInfo(List<ServiceInfo> serviceInfos)
    {
        DbHelper.Db.Updateable(serviceInfos)
            .UpdateColumns(info => new
                {  info.VisitedAmount })
            .ExecuteCommand();
    }

    private static readonly object LockConfig = new();

    /// <summary>
    /// 初始化配置
    /// </summary>
    public static void InitConfig()
    {
        if (MyCloudConstants.Config != null && !string.IsNullOrEmpty(MyCloudConstants.Config.ZuulUrl)) return;
        lock (LockConfig)
        {
            if (MyCloudConstants.Config != null && !string.IsNullOrEmpty(MyCloudConstants.Config.ZuulUrl)) return;

            var serviceConfig = App.GetConfig<ServiceConfig>(nameof(ServiceConfig));
            if (serviceConfig != null)
            {
                MyCloudConstants.Config = serviceConfig;
                GlobalConfig.ServeName = MyCloudConstants.Config.Name;
                if (MyCloudConstants.Config.IsZuul)
                {
                    CloudUtil.GetServiceInfo(true);
                    CloudUtil.GetRoute(true);
                }
            }
        }
    }

    /// <summary>
    /// 获取服务
    /// </summary>
    public static ServiceInfo? GetService(this List<ServiceInfo>? serviceInfos, string route)
    {
        if (serviceInfos == null)
        {
            return default;
        }

        var infos = serviceInfos.FindAll(info => !info.Forbidden && (info.Path == route || info.Name == route));
        if (infos.Count > 0)
        {
            infos.Sort((info, info2) => info.VisitedAmount - info2.VisitedAmount);
            var serviceInfo = infos.Find(info => info.Online && !info.OnExecuting);
            if (serviceInfo != null)
            {
                return serviceInfo;
            }

            serviceInfo = infos.Find(info => info.Online);
            return serviceInfo ?? infos.First();
        }

        return default;
    }

    /// <summary>
    /// 获取服务
    /// </summary>
    public static List<ServiceInfo>? GetServiceList(this List<ServiceInfo>? serviceInfos, string route)
    {
        if (serviceInfos == null)
        {
            return default;
        }

        var infos = serviceInfos.FindAll(info => !info.Forbidden && (info.Path == route || info.Name == route));
        if (infos.Count > 0)
        {
            infos.Sort((info, info2) =>
            {
                if (info.Online && info2.Online)
                {
                    if (info.OnExecuting == info2.OnExecuting)
                    {
                        return info.VisitedAmount - info2.VisitedAmount;
                    }

                    return info.OnExecuting ? 1 : -1; //OnExecuting靠后
                }

                if (!info.Online && !info2.Online)
                {
                    return 0;
                }

                return info.Online ? -1 : 1; //Online靠前
            });
            return infos;
        }

        return default;
    }

    /*/// <summary>
    /// 同步路由
    /// </summary>
    public static void UpdateRoute()
    {
        var routes = DbHelper.Db.Queryable<SysCloudRoute>().Where(route => !route.Forbidden).ToList();
        SetRoute(routes);
    }*/

    /// <summary>
    /// 添加日志
    /// </summary>
    public static void AddLog(this ServiceInfo serviceInfo, string action, string detail)
    {
        MyCloudConstants.Db.Insertable(new SysCloudLog
        {
            ServerId = serviceInfo.Id,
            Server = serviceInfo.Name,
            Action = action,
            Detail = detail,
            Time = CommonUtil.LocalDateTime()
        }).ExecuteCommand();
        WebUtil.LogSys(serviceInfo.Name + action + detail);
    }

    /// <summary>
    /// 添加注册日志
    /// </summary>
    public static void AddRegisterLog(this ServiceInfo serviceInfo)
    {
        serviceInfo.AddLog("Register", "服务注册！");
    }

    /// <summary>
    /// 添加离线日志
    /// </summary>
    public static void AddOfflineLog(this ServiceInfo serviceInfo)
    {
        serviceInfo.AddLog("Offline", "服务离线！");
    }

    /// <summary>
    /// 添加在线日志
    /// </summary>
    public static void AddOnlineLog(this ServiceInfo serviceInfo)
    {
        serviceInfo.AddLog("Online", "服务在线！");
    }
}

/// <summary>
/// 云服务类型
/// </summary>
public enum CloudModalType
{
    /// <summary>
    /// 网关
    /// </summary>
    Zuul,

    /// <summary>
    /// 服务
    /// </summary>
    Service
}